//
// (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
// All rights reserved.
//

/* Copyright (c) 2001-2008, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use _in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions _in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer _in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


using System;
using System.Text;
using EffiProzDB.Lib;
using EffiProzDB.DataTypes;

namespace EffiProzDB.RowIO
{

    /**
     *  Provides methods for reading the data for a row from a
     *  byte array. The format of data is that used for storage of cached
     *  tables by v.1.6.x databases, apart from strings.
     *
     * @author sqlbob@users (RMP)
     * @author fredt@users
     * @version 1.7.2
     * @since 1.7.0
     */
    public class RowInputBinary : RowInputBase, RowInputInterface
    {

        private RowOutputBinary _out;

        public RowInputBinary()
            : base()
        {

        }

        public RowInputBinary(byte[] buf)
            : base(buf)
        {

        }

        /**
         * uses the byte[] buffer from _out. At each reset, the buffer is set
         * to the current one for _out.
         */
        public RowInputBinary(RowOutputBinary _out)
            : base(_out.getBuffer())
        {

            this._out = _out;
        }

        protected byte[] readByteArray()
        {

            byte[] b = new byte[readInt()];

            readFully(b);

            return b;
        }

        public override int readType()
        {
            return readShort();
        }

        public short readShortData()
        {
            return readShort();
        }

        public override int readIntData()
        {
            return readInt();
        }

        public override long readLongData()
        {
            return readLong();
        }

        public override string readString()
        {

            int length = readInt();

            //byte[] tmp = new byte[length];
            //read(tmp, 0, length);
            //string s = Encoding.UTF8.GetString(tmp);
           string s = StringConverter.readUTF(buf, pos, length);

            pos += length;

            return s;
        }

        protected override bool checkNull()
        {

            int b = readByte();

            return b == 0 ? true
                          : false;
        }

        protected override string readChar(int type)
        {
            return readString();
        }

        protected override int? readSmallint()
        {
            return readShort();
        }

        protected override int? readInteger()
        {
            return readInt();
        }

        protected override long? readBigint()
        {
            return readLong();
        }

        protected override double? readReal(int type)
        {
            return BitConverter.Int64BitsToDouble(readLong());
        }

        protected override Decimal? readDecimal()
        {
            int[] bits = new int[4];
            bits[0] = readInt();
            bits[1] = readInt();
            bits[2] = readInt();
            bits[3] = readInt();

            Decimal d =  new Decimal(bits);          
            return d;
        }

        protected override bool? readBit()
        {
            return readbool() ? true
                                 : false;
        }

        protected override DateTime? readTime()
        {
            return readDateTime();
        }

        protected override DateTime? readDate()
        {
            DateTime date  = readDateTime();
            return date;
        }

        protected override DateTime? readTimestamp()
        {
            DateTime date = readDateTime();
            return date;
        }

        protected override Object readOther()
        {
            return new DotNetObject(readByteArray());
        }

        protected override Binary readBinary(int type)
        {
            return new Binary(readByteArray(), false);
        }

        /**
         *  Used to reset the row, ready for Result data to be written into the
         *  byte[] buffer by an external routine.
         *
         */
        public void resetRow(int rowsize)
        {
            if (_out != null)
            {
                _out.reset(rowsize);

                buf = _out.getBuffer();
            }

            base.reset();
        }

        /**
         *  Used to reset the row, ready for a new db row to be written into the
         *  byte[] buffer by an external routine.
         *
         */
        public override void resetRow(int filepos, int rowsize)
        {
            if (_out != null)
            {
                _out.reset(rowsize);

                buf = _out.getBuffer();
            }

            base.resetRow(filepos, rowsize);
        }
    }
}